/**
* @Title: Java2Json.java
* @Description: ${TODO} 类描述
* @Copyright 方正国际软件有限公司,Inc.Allrightsreserved.
 * @author Founder 
* @date 2011-7-25 12:51:23
* @version V1.0 
 */
package com.founder.android.parser;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class Java2Json extends JSONObject {
	
	public Java2Json(Object bean) {
        super();
        populateMap(bean);
    }
	
	@SuppressWarnings("unchecked")
	public Java2Json(Map map) {
		super();
        if (map != null) {
            try {
				Iterator i = map.entrySet().iterator();
				while (i.hasNext()) {
				    Map.Entry e = (Map.Entry)i.next();
				    this.put(e.getKey().toString(), wrap(e.getValue()));
				}
			} catch (JSONException e) {
			}
        }
    }
	
	@SuppressWarnings("unchecked")
    private void populateMap(Object bean) {
        Class klass = bean.getClass();

// If klass is a System class then set includeSuperClass to false. 

        boolean includeSuperClass = klass.getClassLoader() != null;

        Method[] methods = (includeSuperClass) ?
                klass.getMethods() : klass.getDeclaredMethods();
        for (int i = 0; i < methods.length; i += 1) {
            try {
                Method method = methods[i];
                if (Modifier.isPublic(method.getModifiers())) {
                    String name = method.getName();
                    String key = "";
                    if (name.startsWith("get")) {
                    	if (name.equals("getClass") || 
                    			name.equals("getDeclaringClass")) {
                    		key = "";
                    	} else {
                    		key = name.substring(3);
                    	}
                    } else if (name.startsWith("is")) {
                        key = name.substring(2);
                    }
                    if (key.length() > 0 &&
                            Character.isUpperCase(key.charAt(0)) &&
                            method.getParameterTypes().length == 0) {
                        if (key.length() == 1) {
                            key = key.toLowerCase();
                        } else if (!Character.isUpperCase(key.charAt(1))) {
                            key = key.substring(0, 1).toLowerCase() +
                                key.substring(1);
                        }

                        Object result = method.invoke(bean, (Object[])null);

                        this.put(key, wrap(result));
                    }
                }
            } catch (Exception ignore) {
            }
        }
    }
    
    /**
     * Wrap an object, if necessary. If the object is null, return the NULL 
     * object. If it is an array or collection, wrap it in a JSONArray. If 
     * it is a map, wrap it in a JSONObject. If it is a standard property 
     * (Double, String, et al) then it is already wrapped. Otherwise, if it 
     * comes from one of the java packages, turn it into a string. And if 
     * it doesn't, try to wrap it in a JSONObject. If the wrapping fails,
     * then null is returned.
     *
     * @param object The object to wrap
     * @return The wrapped value
     */
	@SuppressWarnings("unchecked")
    static Object wrap(Object object) {
        try {
            if (object == null) {
                return NULL;
            }
            if (object instanceof JSONObject || object instanceof JSONArray || 
           		 object instanceof Byte   || object instanceof Character ||
                    object instanceof Short  || object instanceof Integer   ||
                    object instanceof Long   || object instanceof Boolean   || 
                    object instanceof Float  || object instanceof Double    ||
                    object instanceof String || NULL.equals(object)) {
                return object;
            }
            
            if (object instanceof Collection) {
                return new Java2JsonArray((Collection)object);
            }
            if (object.getClass().isArray()) {
                return new Java2JsonArray(object);
            }
            if (object instanceof Map) {
                return new Java2Json((Map)object);
            }
            Package objectPackage = object.getClass().getPackage();
            String objectPackageName = ( objectPackage != null ? objectPackage.getName() : "" );
            if (objectPackageName.startsWith("java.") ||
           		 objectPackageName.startsWith("javax.") ||
           		 object.getClass().getClassLoader() == null) {
                return object.toString();
            }
            return new Java2Json(object);
        } catch(Exception exception) {
            return null;
        }
    }
}